﻿
#region Using Directives.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Text;
using System.Windows.Forms;
using ExtendedDotNET.Controls.ImageCheckBox;
using GDFlacTool.Common;
using GDFlacTool.Properties;
using CheckState = System.Windows.Forms.CheckState;

#endregion

namespace GDFlacTool.Forms
{
    public partial class FormMultiTagEditor : Form
    {
        #region Fields.

        private readonly IList<Track> _tracks;
        private readonly Track _selectedTrack;
        private readonly bool _allTracksHasImage;
        private readonly string _currentPath;
        private byte[] _imageByteArray;
        private Image _image;

        #endregion

        #region Constructors.

        public FormMultiTagEditor(IList<Track> tracks, Track selectedTrack, bool allTracksHasImage, string currentPath, bool reset)
        {
            InitializeComponent();

            _tracks = tracks;
            _selectedTrack = selectedTrack;
            _allTracksHasImage = allTracksHasImage;
            _currentPath = currentPath;

            ucCase.CaseChecked = MultiTagEditorSettings.Default.UcCaseChecked;
            ucCase.Case = (CaseType)MultiTagEditorSettings.Default.UcCaseSelectedType;
            tabMain.SelectedIndex = MultiTagEditorSettings.Default.TabMainSelectedIndex;

            if (reset)
            {
                ResetCheckboxes();
            }

            picCoverArt.AllowDrop = true;

            if (_tracks.Count > 0)
            {
                Init(_tracks[0]);
            }
            else
            {
                btnSave.Enabled = false;
            }
        }

        #endregion

        #region Properties.

        public byte[] GetImageByteArray
        {
            get { return _imageByteArray; }
        }

        public Image GetImage
        {
            get { return _image; }
        }

        #endregion

        #region Form Events.

        private void FormMultiTagEditor_Load(object sender, EventArgs e)
        {
            icbTitle.Checked = MultiTagEditorSettings.Default.ChkTitleChecked;
            icbArtist.Checked = MultiTagEditorSettings.Default.ChkArtistChecked;
            icbAlbum.Checked = MultiTagEditorSettings.Default.ChkAlbumChecked;
            icbAlbumArtist.Checked = MultiTagEditorSettings.Default.ChkAlbumArtistChecked;
            icbYear.Checked = MultiTagEditorSettings.Default.ChkYearChecked;
            icbGenre.Checked = MultiTagEditorSettings.Default.ChkGenreChecked;
            icbIsrc.Checked = MultiTagEditorSettings.Default.ChkIsrcChecked;
            icbComment.Checked = MultiTagEditorSettings.Default.ChkCommentChecked;
            icbComposer.Checked = MultiTagEditorSettings.Default.ChkComposerChecked;
            icbOriginalArtist.Checked = MultiTagEditorSettings.Default.ChkOriginalArtistChecked;
            icbCopyright.Checked = MultiTagEditorSettings.Default.ChkCopyrightChecked;
            icbUrl.Checked = MultiTagEditorSettings.Default.ChkUrlChecked;
            icbEncodedBy.Checked = MultiTagEditorSettings.Default.ChkEncodedByChecked;
            icbTrack.Checked = MultiTagEditorSettings.Default.ChkTrackChecked;
            icbDisc.Checked = MultiTagEditorSettings.Default.ChkDiscChecked;
            icbCatalog.Checked = MultiTagEditorSettings.Default.ChkCatalogChecked;
            icbRating.Checked = MultiTagEditorSettings.Default.ChkRatingChecked;
            icbMood.Checked = MultiTagEditorSettings.Default.ChkMoodChecked;
            icbQuality.Checked = MultiTagEditorSettings.Default.ChkQualityChecked;
            icbBpm.Checked = MultiTagEditorSettings.Default.ChkBpmChecked;
            chkLyrics.Checked = MultiTagEditorSettings.Default.ChkLyricsChecked;
            chkConductor.Checked = MultiTagEditorSettings.Default.ChkConductorChecked;
            chkLyricist.Checked = MultiTagEditorSettings.Default.ChkLyricistChecked;
            chkOriginalLyricist.Checked = MultiTagEditorSettings.Default.ChkOriginalLyricistChecked;
            chkLabel.Checked = MultiTagEditorSettings.Default.ChkLabelChecked;
            chkRemixedBy.Checked = MultiTagEditorSettings.Default.ChkRemixedByChecked;
            chkRadioStationName.Checked = MultiTagEditorSettings.Default.ChkRadioStationNameChecked;
            chkAudioFileUrl.Checked = MultiTagEditorSettings.Default.ChkAudioFileUrlChecked;
            chkAuthorUrl.Checked = MultiTagEditorSettings.Default.ChkAuthorUrlChecked;
            chkAudioSourceUrl.Checked = MultiTagEditorSettings.Default.ChkAudioSourceUrlChecked;
            chkRadioStationUrl.Checked = MultiTagEditorSettings.Default.ChkRadioStationUrlChecked;
            chkBuyCdUrl.Checked = MultiTagEditorSettings.Default.ChkBuyCdUrlChecked;
        }

        private void FormMultiTagEditor_FormClosing(object sender, FormClosingEventArgs e)
        {
            MultiTagEditorSettings.Default.UcCaseChecked = ucCase.CaseChecked;
            MultiTagEditorSettings.Default.UcCaseSelectedType = (int)ucCase.GetCaseType();
            MultiTagEditorSettings.Default.TabMainSelectedIndex = tabMain.SelectedIndex;

            MultiTagEditorSettings.Default.ChkTitleChecked = icbTitle.Checked;
            MultiTagEditorSettings.Default.ChkArtistChecked = icbArtist.Checked;
            MultiTagEditorSettings.Default.ChkAlbumChecked = icbAlbum.Checked;
            MultiTagEditorSettings.Default.ChkAlbumArtistChecked = icbAlbumArtist.Checked;
            MultiTagEditorSettings.Default.ChkYearChecked = icbYear.Checked;
            MultiTagEditorSettings.Default.ChkGenreChecked = icbGenre.Checked;
            MultiTagEditorSettings.Default.ChkIsrcChecked = icbIsrc.Checked;
            MultiTagEditorSettings.Default.ChkCommentChecked = icbComment.Checked;
            MultiTagEditorSettings.Default.ChkComposerChecked = icbComposer.Checked;
            MultiTagEditorSettings.Default.ChkOriginalArtistChecked = icbOriginalArtist.Checked;
            MultiTagEditorSettings.Default.ChkCopyrightChecked = icbCopyright.Checked;
            MultiTagEditorSettings.Default.ChkUrlChecked = icbUrl.Checked;
            MultiTagEditorSettings.Default.ChkEncodedByChecked = icbEncodedBy.Checked;
            MultiTagEditorSettings.Default.ChkTrackChecked = icbTrack.Checked;
            MultiTagEditorSettings.Default.ChkDiscChecked = icbDisc.Checked;
            MultiTagEditorSettings.Default.ChkCatalogChecked = icbCatalog.Checked;
            MultiTagEditorSettings.Default.ChkRatingChecked = icbRating.Checked;
            MultiTagEditorSettings.Default.ChkMoodChecked = icbMood.Checked;
            MultiTagEditorSettings.Default.ChkQualityChecked = icbQuality.Checked;
            MultiTagEditorSettings.Default.ChkBpmChecked = icbBpm.Checked;
            MultiTagEditorSettings.Default.ChkLyricsChecked = chkLyrics.Checked;
            MultiTagEditorSettings.Default.ChkConductorChecked = chkConductor.Checked;
            MultiTagEditorSettings.Default.ChkLyricistChecked = chkLyricist.Checked;
            MultiTagEditorSettings.Default.ChkOriginalLyricistChecked = chkOriginalLyricist.Checked;
            MultiTagEditorSettings.Default.ChkLabelChecked = chkLabel.Checked;
            MultiTagEditorSettings.Default.ChkRemixedByChecked = chkRemixedBy.Checked;
            MultiTagEditorSettings.Default.ChkRadioStationNameChecked = chkRadioStationName.Checked;
            MultiTagEditorSettings.Default.ChkAudioFileUrlChecked = chkAudioFileUrl.Checked;
            MultiTagEditorSettings.Default.ChkAuthorUrlChecked = chkAuthorUrl.Checked;
            MultiTagEditorSettings.Default.ChkAudioSourceUrlChecked = chkAudioSourceUrl.Checked;
            MultiTagEditorSettings.Default.ChkRadioStationUrlChecked = chkRadioStationUrl.Checked;
            MultiTagEditorSettings.Default.ChkBuyCdUrlChecked = chkBuyCdUrl.Checked;

            MultiTagEditorSettings.Default.Save();
        }

        #endregion

        #region Init Form.

        private void Init(Track track)
        {
            Text = string.Format("Tag Editor [{0} File(s)]", _tracks.Count);

            LoadGenreCombo();
            LoadRatingCombo();

            if (_tracks.Count == 1)
            {
                txtFile.Text = Functions.ShortenName(track.FullPath, 110); txtFile.Text = Functions.ShortenName(track.FullPath, 110);
            }
            else
            {
                lblFile.Text = "Folder:";
                txtFile.Text = Functions.ShortenName(Path.GetDirectoryName(track.FullPath), 110);
            }
                
            txtTitle.Text = track.Title;
            txtArtist.Text = track.Artist;
            txtAlbum.Text = track.Album;
            txtAlbumArtist.Text = track.Albumartist;
            txtYear.Text = track.Year;

            if (cboGenre.Items.Contains(track.Genre))
            {
                int index = cboGenre.Items.IndexOf(track.Genre);

                cboGenre.SelectedIndex = index;
            }
            else
            {
                cboGenre.Text = track.Genre;
            }

            try
            {
                cboRating.SelectedValue = (Rating)Enum.Parse(typeof(Rating), track.Rating);
            }
            catch (Exception)
            {
                cboRating.SelectedValue = Rating.Unrated;
            }

            if (string.IsNullOrEmpty(track.Quality))
            {
                cboQuality.Text = string.Empty;
            }
            else
            {
                cboQuality.Text = track.Quality;
            }

            cboMood.SelectedItem = track.Mood;
            txtBpm.Text = track.Bpm;

            txtIsrc.Text = track.Catalog;
            txtComment.Text = track.Comment;
            txtTrack.Text = track.TrackNumber;
            txtDisc.Text = track.DiscNumber;
            txtCatalog.Text = track.Catalog;
            txtIsrc.Text = track.Isrc;
            txtComposer.Text = track.Composer;
            txtOriginalArtist.Text = track.Originalartist;
            txtCopyright.Text = track.Copyright;
            txtUrl.Text = track.Url;
            txtEncodedBy.Text = track.EncodedBy;
            txtLyrics.Text = track.Lyrics;

            if (_allTracksHasImage)
            {
                _image = _tracks[0].ArtImage;
                _imageByteArray = _tracks[0].ArtByteArray;
                picCoverArt.Image = _image;
                lblFolderCoverArtInfo.Text = String.Format("Picture: {0} x {1}, {2}", _image.Width, _image.Height, Functions.GetFileArtSizeFromBytes(_imageByteArray.Length));
                btnSaveArt.Enabled = true;
                lblDragDrop.Visible = false;
            }
            else
            {
                if (_selectedTrack != null)
                {
                    if (_selectedTrack.HasFileCoverArt)
                    {
                        _image = _selectedTrack.ArtImage;
                        _imageByteArray = _selectedTrack.ArtByteArray;

                        picCoverArt.Image = _image;
                        lblFolderCoverArtInfo.Text = String.Format("Picture: {0} x {1}, {2}", _image.Width, _image.Height, Functions.GetFileArtSizeFromBytes(_selectedTrack.ArtSize));
                        btnSaveArt.Enabled = true;
                    }
                    else
                    {
                        btnSaveArt.Enabled = false;
                    }
                }
            }

            txtConductor.Text = track.Conductor;
            txtLyricist.Text = track.Lyricist;
            txtOriginalLyricist.Text = track.OriginalLyricist;
            txtLabel.Text = track.Label;
            txtRemixedBy.Text = track.RemixedBy;
            txtRadioStationName.Text = track.RadioStationName;
            txtAudioFileUrl.Text = track.AudioFileUrl;
            txtAuthorUrl.Text = track.AuthorUrl;
            txtAudioSourceUrl.Text = track.AudioSourceUrl;
            txtRadioStationUrl.Text = track.RadioStationUrl;
            txtBuyCdUrl.Text = track.BuyCdUrl;
        }

        #endregion

        #region CheckBox Events.

        private void icbTitle_CheckedChange(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtTitle.Enabled = icbTitle.Checked;
        }

        private void icbArtist_CheckedChange(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtArtist.Enabled = icbArtist.Checked;
        }

        private void icbAlbum_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtAlbum.Enabled = icbAlbum.Checked;
        }

        private void icbYear_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtYear.Enabled = icbYear.Checked;
        }

        private void icbAlbumArtist_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtAlbumArtist.Enabled = icbAlbumArtist.Checked;
        }

        private void icbGenre_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            cboGenre.Enabled = icbGenre.Checked;
        }

        private void icbIsrc_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtIsrc.Enabled = icbIsrc.Checked;
        }

        private void icbComment_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtComment.Enabled = icbComment.Checked;
        }

        private void icbTrack_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtTrack.Enabled = icbTrack.Checked;
        }

        private void icbDisc_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtDisc.Enabled = icbDisc.Checked;
        }

        private void icbCatalog_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtCatalog.Enabled = icbCatalog.Checked;
        }

        private void icbComposer_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtComposer.Enabled = icbComposer.Checked;
        }

        private void icbOriginalArtist_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtOriginalArtist.Enabled = icbOriginalArtist.Checked;
        }

        private void icbCopyright_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtCopyright.Enabled = icbCopyright.Checked;
        }

        private void icbUrl_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtUrl.Enabled = icbUrl.Checked;
        }

        private void icbEncodedBy_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtEncodedBy.Enabled = icbEncodedBy.Checked;
        }

        private void icbRating_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            cboRating.Enabled = icbRating.Checked;
        }

        private void icbMood_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            cboMood.Enabled = icbMood.Checked;
        }

        private void icbQuality_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            cboQuality.Enabled = icbQuality.Checked;
        }

        private void icbBpm_CheckedChanged(object sender, ExtendedDotNET.Controls.ImageCheckBox.CheckedChangeEventArgs e)
        {
            txtBpm.Enabled = icbBpm.Checked;
        }

        private void chkArt_CheckedChanged(object sender, EventArgs e)
        {
            btnRemoveArt.Enabled = chkArt.Checked;
        }

        private void chkLyrics_CheckedChanged(object sender, EventArgs e)
        {
            txtLyrics.Enabled = chkLyrics.Checked;
        }

        private void chkConductor_CheckedChanged(object sender, EventArgs e)
        {
            txtConductor.Enabled = chkConductor.Checked;
        }

        private void chkLyricist_CheckedChanged(object sender, EventArgs e)
        {
            txtLyricist.Enabled = chkLyricist.Checked;
        }

        private void chkOriginalLyricist_CheckedChanged(object sender, EventArgs e)
        {
            txtOriginalLyricist.Enabled = chkOriginalLyricist.Checked;
        }

        private void chkLabel_CheckedChanged(object sender, EventArgs e)
        {
            txtLabel.Enabled = chkLabel.Checked;
        }

        private void chkRemixedBy_CheckedChanged(object sender, EventArgs e)
        {
            txtRemixedBy.Enabled = chkRemixedBy.Checked;
        }

        private void chkRadioStationName_CheckedChanged(object sender, EventArgs e)
        {
            txtRadioStationName.Enabled = chkRadioStationName.Checked;
        }

        private void chkAudioFileUrl_CheckedChanged(object sender, EventArgs e)
        {
            txtAudioFileUrl.Enabled = chkAudioFileUrl.Checked;
        }

        private void chkAuthorUrl_CheckedChanged(object sender, EventArgs e)
        {
            txtAuthorUrl.Enabled = chkAuthorUrl.Checked;
        }

        private void chkAudioSourceUrl_CheckedChanged(object sender, EventArgs e)
        {
            txtAudioSourceUrl.Enabled = chkAudioSourceUrl.Checked;
        }

        private void chkRadioStationUrl_CheckedChanged(object sender, EventArgs e)
        {
            txtRadioStationUrl.Enabled = chkRadioStationUrl.Checked;
        }

        private void chkBuyCdUrl_CheckedChanged(object sender, EventArgs e)
        {
            txtBuyCdUrl.Enabled = chkBuyCdUrl.Checked;
        }

        #endregion

        #region Button Events.

        private void btnSave_Click(object sender, EventArgs e)
        {
            UpdateTrackTags();
        }

        private void btnCheckAll_Click(object sender, EventArgs e)
        {
            foreach (Control ctrl in tabGeneral.Controls)
            {
                if (ctrl.GetType() == (typeof(CheckBox)))
                {
                    if (ctrl.Name != "chkCompilation")
                        ((CheckBox)ctrl).Checked = true;
                }
                if (ctrl.GetType() == (typeof(ImageCheckBox)))
                {
                    if (ctrl.Name != "chkCompilation")
                        ((ImageCheckBox)ctrl).Checked = true;
                }
            }

            chkArt.Checked = true;

            chkLyrics.Checked = true;

            foreach (Control ctrl in tabAdditional.Controls)
            {
                if (ctrl.GetType() == (typeof(CheckBox)))
                {
                    ((CheckBox)ctrl).Checked = true;
                }

                if (ctrl.GetType() == (typeof(ImageCheckBox)))
                {
                    ((ImageCheckBox)ctrl).Checked = true;
                }
            }
        }

        private void btnUncheckAll_Click(object sender, EventArgs e)
        {
            foreach (Control ctrl in tabGeneral.Controls)
            {
                if (ctrl.GetType() == (typeof(CheckBox)))
                {
                    if (ctrl.Name != "chkCompilation")
                        ((CheckBox)ctrl).Checked = false;
                }

                if (ctrl.GetType() == (typeof(ImageCheckBox)))
                {
                    if (ctrl.Name != "chkCompilation")
                        ((ImageCheckBox)ctrl).Checked = false;
                }
            }

            chkArt.Checked = false;

            chkLyrics.Checked = false;

            foreach (Control ctrl in tabAdditional.Controls)
            {
                if (ctrl.GetType() == (typeof(CheckBox)))
                {
                    ((CheckBox)ctrl).Checked = false;
                }

                if (ctrl.GetType() == (typeof(ImageCheckBox)))
                {
                    ((ImageCheckBox)ctrl).Checked = false;
                }
            }
        }

        private void btnClearAll_Click(object sender, EventArgs e)
        {
            foreach (Control ctrl in tabGeneral.Controls)
            {
                if (ctrl.GetType() == (typeof(TextBox)))
                {
                    if (ctrl.Name != "txtFile")
                        ((TextBox)ctrl).Text = string.Empty;
                }

                if (ctrl.GetType() == (typeof(ComboBox)))
                {
                    ((ComboBox)ctrl).Text = string.Empty;
                }
            }

            RemoveArt();

            txtLyrics.Clear();

            foreach (Control ctrl in tabAdditional.Controls)
            {
                if (ctrl.GetType() == (typeof(TextBox)))
                {
                    ((TextBox)ctrl).Text = string.Empty;
                }
            }
        }

        private void btnAddArt_Click(object sender, EventArgs e)
        {
            openFileDialog.Title = "Add Flac Cover Art";
            openFileDialog.Filter = "JPG JPEG(*.jpeg,*.jpg,*.jif,*.jpe)|*.jpeg;*.jpg;*.jif;*.jpe|PNG Portable Network Grapics(*.png)|*.png";
            openFileDialog.FilterIndex = 1;
            openFileDialog.InitialDirectory = _currentPath;

            DialogResult open = openFileDialog.ShowDialog(this);

            if (open == DialogResult.OK)
            {
                if (AddArt(openFileDialog.FileName))
                {
                    btnSaveArt.Enabled = true;
                }
                else
                {
                    btnSaveArt.Enabled = false;
                }

                chkArt.Checked = true;
            }
        }

        private void btnSaveArt_Click(object sender, EventArgs e)
        {
            saveFileDialog.Title = @"Save Cover Art Image";
            saveFileDialog.Filter = "JPG(*.JPG)|*.JPG";
            saveFileDialog.FilterIndex = 1;
            saveFileDialog.DefaultExt = "JPG";
            saveFileDialog.FileName = "Folder";
            saveFileDialog.InitialDirectory = _currentPath;

            DialogResult dlgResult = saveFileDialog.ShowDialog(this);

            if (dlgResult == DialogResult.OK)
            {
                SaveArt(saveFileDialog.FileName);
            }
        }

        private void btnRemoveArt_Click(object sender, EventArgs e)
        {
            RemoveArt();
        }

        private void btnLoadFromTextFile_Click(object sender, EventArgs e)
        {
            openFileDialog.Title = "Open Lyric File";
            openFileDialog.Filter = "Lyric File(*.txt)|*.txt";
            openFileDialog.FilterIndex = 1;
            openFileDialog.InitialDirectory = _currentPath;

            DialogResult open = openFileDialog.ShowDialog(this);

            if (open == DialogResult.OK)
            {
                TextReader tr = null;

                try
                {
                    StringBuilder sb = new StringBuilder();
                    tr = new StreamReader(openFileDialog.FileName);
                    string line = null;

                    while ((line = tr.ReadLine()) != null)
                    {
                        sb.AppendLine(line);
                    }

                    txtLyrics.Text = sb.ToString();
                }
                catch (Exception ex)
                {
                    string message = String.Format("There was a problem opening the lyrics file [{0}]\n\n{1}", openFileDialog.FileName, ex.Message);

                    MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    if (tr != null) tr.Close();
                }

                chkLyrics.Checked = true;
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            txtLyrics.Clear();
        }

        private void btnSaveLyrics_Click(object sender, EventArgs e)
        {
            saveFileDialog.Title = @"Save Lyrics To Text File";
            saveFileDialog.Filter = "Lyrics File(*.txt)|*.txt";
            saveFileDialog.FilterIndex = 1;
            saveFileDialog.DefaultExt = "txt";
            saveFileDialog.FileName = "Lyrics";
            saveFileDialog.InitialDirectory = _currentPath;

            DialogResult dlgResult = saveFileDialog.ShowDialog(this);

            if (dlgResult == DialogResult.OK)
            {
                StreamWriter streamWriter = null;

                try
                {
                    var fileInfo = new FileInfo(saveFileDialog.FileName);
                    streamWriter = fileInfo.CreateText();

                    foreach (string line in txtLyrics.Lines)
                    {
                        streamWriter.WriteLine(line);
                    }
                }
                catch (Exception ex)
                {
                    string message = String.Format("There was a problem saving the lyrics file [{0}]\n\n{1}", saveFileDialog.FileName, ex.Message);

                    MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    if (streamWriter != null) streamWriter.Close();
                }
            }
        }

        private void btnRemoveLeftSpaces_Click(object sender, EventArgs e)
        {
            StringBuilder sb = new StringBuilder();

            foreach (string line in txtLyrics.Lines)
            {
                sb.AppendLine(line.TrimStart());
            }

            txtLyrics.Text = sb.ToString();
        }

        private void btnAudioFileUrl_Click(object sender, EventArgs e)
        {
            Functions.OpenUrl(txtAudioFileUrl.Text);
        }

        private void btnAuthorUrl_Click(object sender, EventArgs e)
        {
            Functions.OpenUrl(txtAuthorUrl.Text);
        }

        private void btnAudioSourceUrl_Click(object sender, EventArgs e)
        {
            Functions.OpenUrl(txtAudioSourceUrl.Text);
        }

        private void btnRadioStationUrl_Click(object sender, EventArgs e)
        {
            Functions.OpenUrl(txtRadioStationUrl.Text);
        }

        private void btnBuyCdUrl_Click(object sender, EventArgs e)
        {
            Functions.OpenUrl(txtBuyCdUrl.Text);
        }

        #endregion

        #region Private Methods.

        private void ResetCheckboxes()
        {
            MultiTagEditorSettings.Default.ChkTitleChecked = false;
            MultiTagEditorSettings.Default.ChkArtistChecked = false;
            MultiTagEditorSettings.Default.ChkAlbumChecked = false;
            MultiTagEditorSettings.Default.ChkAlbumArtistChecked = false;
            MultiTagEditorSettings.Default.ChkYearChecked = false;
            MultiTagEditorSettings.Default.ChkGenreChecked = false;
            MultiTagEditorSettings.Default.ChkIsrcChecked = false;
            MultiTagEditorSettings.Default.ChkCommentChecked = false;
            MultiTagEditorSettings.Default.ChkComposerChecked = false;
            MultiTagEditorSettings.Default.ChkOriginalArtistChecked = false;
            MultiTagEditorSettings.Default.ChkCopyrightChecked = false;
            MultiTagEditorSettings.Default.ChkUrlChecked = false;
            MultiTagEditorSettings.Default.ChkEncodedByChecked = false;
            MultiTagEditorSettings.Default.ChkTrackChecked = false;
            MultiTagEditorSettings.Default.ChkDiscChecked = false;
            MultiTagEditorSettings.Default.ChkCatalogChecked = false;
            MultiTagEditorSettings.Default.ChkRatingChecked = false;
            MultiTagEditorSettings.Default.ChkMoodChecked = false;
            MultiTagEditorSettings.Default.ChkQualityChecked = false;
            MultiTagEditorSettings.Default.ChkBpmChecked = false;
            MultiTagEditorSettings.Default.ChkLyricsChecked = false;
            MultiTagEditorSettings.Default.ChkConductorChecked = false;
            MultiTagEditorSettings.Default.ChkLyricistChecked = false;
            MultiTagEditorSettings.Default.ChkOriginalLyricistChecked = false;
            MultiTagEditorSettings.Default.ChkLabelChecked = false;
            MultiTagEditorSettings.Default.ChkRemixedByChecked = false;
            MultiTagEditorSettings.Default.ChkRadioStationNameChecked = false;
            MultiTagEditorSettings.Default.ChkAudioFileUrlChecked = false;
            MultiTagEditorSettings.Default.ChkAuthorUrlChecked = false;
            MultiTagEditorSettings.Default.ChkAudioSourceUrlChecked = false;
            MultiTagEditorSettings.Default.ChkRadioStationUrlChecked = false;
            MultiTagEditorSettings.Default.ChkBuyCdUrlChecked = false;

            MultiTagEditorSettings.Default.Save();
        }

        private void LoadGenreCombo()
        {
            string[] genres = Genres.Audio;

            for (int i = 0; i < Genres.Audio.Length; i++)
            {
                cboGenre.Items.Add(genres[i]);
            }
        }

        private void LoadRatingCombo()
        {
            cboRating.DataSource = typeof(Rating).ToList();
            cboRating.DisplayMember = "Value";
            cboRating.ValueMember = "Key";
        }

        private bool AddArt(string path)
        {
            if (File.Exists(path))
            {
                FileStream fs = null;
                MemoryStream ms = new MemoryStream();
                try
                {
                    fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);

                    fs.CopyTo(ms);

                    _imageByteArray = ms.ToArray();

                    Image image = Image.FromStream(fs);

                    _image = image;

                    lblFolderCoverArtInfo.Text = String.Format("Picture: {0} x {1}, {2}", image.Width, image.Height, Functions.GetFolderArtSizeFromFile(path));

                    picCoverArt.Image = image;

                    lblDragDrop.Visible = false;

                    return true;
                }
                catch (Exception ex)
                {
                    string message = String.Format("There was a problem opening the cover art picture file [{0}]\n\n{1}", path, ex.Message);

                    MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    if (fs != null) fs.Close();
                    ms.Close();
                }
            }

            picCoverArt.Image = null;
            lblFolderCoverArtInfo.Text = "Picture:";
            return false;
        }

        private void SaveArt(string path)
        {
            byte[] bytes = _imageByteArray;

            MemoryStream ms = null;
            FileStream fs = null;

            try
            {
                ms = new MemoryStream(bytes);

                fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);

                ms.CopyTo(fs);

                fs.Flush();
            }
            catch (Exception ex)
            {
                string message = String.Format("There was a problem saving cover art to file [{0}]\n\n{1}", path, ex.Message);

                MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                if (fs != null) fs.Close();
                if (ms != null) ms.Close();
            }
        }

        private void RemoveArt()
        {
            picCoverArt.Image = null;
            _imageByteArray = null;
            _image = null;
            lblFolderCoverArtInfo.Text = "Picture:";
            btnSaveArt.Enabled = false;
            lblDragDrop.Visible = true;
        }

        private string CheckCase(string text, bool changeCase, CaseType type)
        {
            TextInfo myTI = new CultureInfo("en-US", false).TextInfo;

            string value = text;

            if (changeCase)
            {
                if (type == CaseType.Lower)
                {
                    value = myTI.ToLower(text);
                }

                if (type == CaseType.Upper)
                {
                    value = myTI.ToUpper(text);
                }

                if (type == CaseType.FirstLetter)
                {
                    value = myTI.ToTitleCase(text.ToLower());
                }

                if (type == CaseType.FirstWord)
                {
                    value = text.ToLower().ToUpperFirstLetter();
                }
            }

            return value;
        }

        #endregion

        #region Update Tag Information

        private void UpdateTrackTags()
        {
            foreach (Track track in _tracks)
            {
                if (icbTitle.Checked)
                {
                    track.Title = CheckCase(txtTitle.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsTitleChanged = true;
                }

                if (icbArtist.Checked)
                {
                    track.Artist = CheckCase(txtArtist.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsArtistChanged = true;
                }

                if (icbAlbum.Checked)
                {
                    track.Album = CheckCase(txtAlbum.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsAlbumChanged = true;
                }

                if (icbAlbumArtist.Checked)
                {
                    track.Albumartist = CheckCase(txtAlbumArtist.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsAlbumArtistChanged = true;
                }

                if (icbYear.Checked)
                {
                    track.Year = CheckCase(txtYear.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsYearChanged = true;
                }

                if (icbGenre.Checked)
                {
                    track.Genre = CheckCase(cboGenre.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsGenreChanged = true;
                }

                if (icbIsrc.Checked)
                {
                    track.Isrc = txtIsrc.Text;
                    track.IsIsrcChanged = true;
                }

                if (icbComment.Checked)
                {
                    track.Comment = CheckCase(txtComment.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsCommentChanged = true;
                }

                if (icbComposer.Checked)
                {
                    track.Composer = CheckCase(txtComposer.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsComposerChanged = true;
                }

                if (icbOriginalArtist.Checked)
                {
                    track.Originalartist = CheckCase(txtOriginalArtist.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsOriginalArtistChanged = true;
                }

                if (icbCopyright.Checked)
                {
                    track.Copyright = CheckCase(txtCopyright.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsCopyrightChanged = true;
                }

                if (icbUrl.Checked)
                {
                    track.Url = CheckCase(txtUrl.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsUrlChanged = true;
                }

                if (icbEncodedBy.Checked)
                {
                    track.EncodedBy = CheckCase(txtEncodedBy.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsEncodedByChanged = true;
                }

                if (chkCompilation.CheckState != CheckState.Indeterminate)
                {
                    if (chkCompilation.CheckState == CheckState.Checked)
                    {
                        track.Compilation = true;
                    }
                    else
                    {
                        track.Compilation = false;
                    }

                    track.IsCompilationChanged = true;
                }

                if (icbTrack.Checked)
                {
                    track.TrackNumber = txtTrack.Text;
                    track.IsTrackNumberChanged = true;
                }

                if (icbDisc.Checked)
                {
                    track.DiscNumber = txtDisc.Text;
                    track.IsDiscNumberChanged = true;
                }

                if (icbCatalog.Checked)
                {
                    track.Catalog = txtCatalog.Text;
                    track.IsCatalogChanged = true;
                }

                if (icbRating.Checked)
                {
                    if (!string.IsNullOrEmpty(cboRating.ValueMember))
                    {
                        var rating = (Rating)Enum.Parse(typeof(Rating), cboRating.SelectedValue.ToString());

                        track.Rating = ((int)rating).ToString(CultureInfo.InvariantCulture);
                    }
                    else
                    {
                        track.Rating = "0";
                    }

                    track.IsRatingChanged = true;
                }

                if (icbMood.Checked)
                {
                    track.Mood = CheckCase(cboMood.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsMoodChanged = true;
                }

                if (icbQuality.Checked)
                {
                    track.Quality = CheckCase(cboQuality.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsQualityChanged = true;
                }

                if (icbBpm.Checked)
                {
                    track.Bpm = txtBpm.Text;
                    track.IsBpmChanged = true;
                }

                if (chkArt.Checked)
                {
                    track.IsCoverArtChanged = true;
                }
                else
                {
                    track.IsCoverArtChanged = false;
                }

                if (chkLyrics.Checked)
                {
                    track.Lyrics = txtLyrics.Text;
                    track.IsLyricsChanged = true;
                }

                if (chkConductor.Checked)
                {
                    track.Conductor = CheckCase(txtConductor.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsConductorChanged = true;
                }

                if (chkLyricist.Checked)
                {
                    track.Lyricist = CheckCase(txtLyricist.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsLyricistChanged = true;
                }

                if (chkOriginalLyricist.Checked)
                {
                    track.OriginalLyricist = CheckCase(txtOriginalLyricist.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsOriginalLyricistChanged = true;
                }

                if (chkLabel.Checked)
                {
                    track.Label = CheckCase(txtLabel.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsLabelChanged = true;
                }

                if (chkRemixedBy.Checked)
                {
                    track.RemixedBy = CheckCase(txtRemixedBy.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsRemixedByChanged = true;
                }

                if (chkRadioStationName.Checked)
                {
                    track.RadioStationName = CheckCase(txtRadioStationName.Text, ucCase.CaseChecked, ucCase.GetCaseType());
                    track.IsRadioStationNameChanged = true;
                }

                if (chkAudioFileUrl.Checked)
                {
                    track.AudioFileUrl = txtAudioFileUrl.Text;
                    track.IsAudioFileUrlChanged = true;
                }

                if (chkAuthorUrl.Checked)
                {
                    track.AuthorUrl = txtAuthorUrl.Text;
                    track.IsAuthorUrlChanged = true;
                }

                if (chkAudioSourceUrl.Checked)
                {
                    track.AudioSourceUrl = txtAudioSourceUrl.Text;
                    track.IsAudioSourceUrlChanged = true;
                }

                if (chkRadioStationUrl.Checked)
                {
                    track.RadioStationUrl = txtRadioStationUrl.Text;
                    track.IsRadioStationUrlChanged = true;
                }

                if (chkBuyCdUrl.Checked)
                {
                    track.BuyCdUrl = txtBuyCdUrl.Text;
                    track.IsBuyCdUrlChanged = true;
                }
            }
        }

        #endregion

        #region Drag And Drop.

        private void picCoverArt_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
            }

            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void picCoverArt_DragDrop(object sender, DragEventArgs e)
        {
            try
            {
                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    string[] filepath = (string[])e.Data.GetData(DataFormats.FileDrop);

                    AddArt(filepath[0]);

                    chkArt.Checked = true;
                    btnAddArt.Enabled = true;
                    btnRemoveArt.Enabled = true;
                    btnSaveArt.Enabled = true;
                }
            }
            catch (Exception ex)
            {
                string message = String.Format("There was a problem adding the cover art picture file!\n\n{0}", ex.Message);

                MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion

    }
}
